package com.cloudinnov.logic.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cloudinnov.dao.AlarmLogDao;
import com.cloudinnov.dao.AlarmWorkOrdersDao;
import com.cloudinnov.dao.AlarmWorkUserDao;
import com.cloudinnov.dao.AttachDao;
import com.cloudinnov.dao.AuthUserDao;
import com.cloudinnov.dao.CompaniesDao;
import com.cloudinnov.dao.EquipmentsDao;
import com.cloudinnov.dao.FaultsDao;
import com.cloudinnov.dao.HelpWorkOrderDao;
import com.cloudinnov.dao.WorkOrderLogsDao;
import com.cloudinnov.logic.AlarmWorkOrdersLogic;
import com.cloudinnov.model.AlarmLog;
import com.cloudinnov.model.AlarmWorkOrders;
import com.cloudinnov.model.AlarmWorkUser;
import com.cloudinnov.model.Attach;
import com.cloudinnov.model.AuthUsers;
import com.cloudinnov.model.Companies;
import com.cloudinnov.model.Equipments;
import com.cloudinnov.model.FaultStat;
import com.cloudinnov.model.HelpWorkOrder;
import com.cloudinnov.model.PageModel;
import com.cloudinnov.model.WorkOrderLogs;
import com.cloudinnov.utils.CodeUtil;
import com.cloudinnov.utils.CommonUtils;
import com.cloudinnov.utils.MailSenderUtil;
import com.cloudinnov.utils.PropertiesUtils;
import com.cloudinnov.websocket.AlarmDialogueWebsocket;
import com.cloudinnov.websocket.CustomerAlarmWebsocket;
import com.cloudinnov.websocket.HomeMapAlarmWebsocket;
import com.cloudinnov.websocket.MyAlarmWebsocket;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @author chengning
 * @date 2016年2月17日上午11:50:41
 * @email ningcheng@cloudinnov.com
 * @remark
 * @version 工单Logic实现类 继承BaseLogicImpl 实现工单Logic接口
 */
@Service("alarmWorkOrdersLogic")
public class AlarmWorkOrdersLogicImpl extends BaseLogicImpl<AlarmWorkOrders> implements AlarmWorkOrdersLogic {
	private static final Logger logger = LoggerFactory.getLogger(AlarmWorkOrdersLogicImpl.class);
	private static final int FAULT_LIKE_HIS_SIZE_START = 0;
	private static final int FAULT_LIKE_HIS_SIZE_END = 5;
	private static final int ONE_DATE_SECONDS = 3600 * 24 * 1000;
	private static final int DEFAULT_COUNT = 1;
	@SuppressWarnings("unused")
	private static final String MY_FAULT_TOTAL = "total";
	private int digit = 5;
	private static final String FAULT_REDIS_SPILT = "_";
	@Autowired
	private AlarmWorkOrdersDao alarmWorkOrdersDao;
	@Autowired
	private WorkOrderLogsDao workOrderLogsDao;
	@Autowired
	private AuthUserDao authUserDao;
	@Autowired
	private AttachDao attachDao;
	@Autowired
	private FaultsDao faultsDao;
	@Autowired
	private EquipmentsDao equipmentsDao;
	@Autowired
	private CompaniesDao companiesDao;
	@Autowired
	private AlarmLogDao alarmLogDao;
	@Autowired
	private HelpWorkOrderDao helpWorkOrderDao;
	@Autowired
	private JedisPool redisPool;
	@Autowired
	private AlarmWorkUserDao alarmWorkUserDao;

	public int save(List<AlarmWorkOrders> alarmWorkOrders) {
		String code = null;
		Jedis redis = null;
		int returnCode = 0;
		try {
			redis = redisPool.getResource();
			for (int i = 0; i < alarmWorkOrders.size(); i++) {
				if (alarmWorkOrders.get(i).getIsCreateOrder() == CommonUtils.FAULT_IS_CERATE_ORDER_NO) {
					break;// 故障码标示不产生工单
				}
				AlarmWorkOrders awo = new AlarmWorkOrders();
				awo.setCode(code);
				awo.setSectionCode(alarmWorkOrders.get(i).getSectionCode());
				awo.setComment(CommonUtils.ORDER_STATUS_NEW_MSG);
				awo.setStatus(CommonUtils.STATUS_NORMAL);
				awo.setOrderStatus(CommonUtils.ORDER_STATUS_NEW);
				awo.setCustomerCode(alarmWorkOrders.get(i).getCompany().getCode());
				awo.setEquipmentCode(alarmWorkOrders.get(i).getEquipment().getCode());
				awo.setFaultChannelCode(alarmWorkOrders.get(i).getFaultChannelCode());
				awo.setFaultCode(alarmWorkOrders.get(i).getFaultCode());
				awo.setDescription(alarmWorkOrders.get(i).getDescription());
				awo.setHandingSuggestion(alarmWorkOrders.get(i).getHandingSuggestion());
				awo.setLanguage(alarmWorkOrders.get(i).getLanguage());
				awo.setFirstTime(String.valueOf(System.currentTimeMillis()));
				awo.setLevel(alarmWorkOrders.get(i).getLevel());
				awo.setPaddingBy(alarmWorkOrders.get(i).getOemPerson().split(CommonUtils.SPLIT_COMMA)[0]);
				if (i == 0) {
					code = CodeUtil.flmCode(digit);
					awo.setCode(code);
					AlarmLog equipmentAlarmLog = new AlarmLog();
					equipmentAlarmLog.setEquipmentCode(alarmWorkOrders.get(i).getEquipment().getCode());
					equipmentAlarmLog.setChannelCode(alarmWorkOrders.get(i).getFaultChannelCode());
					equipmentAlarmLog.setFaultCode(alarmWorkOrders.get(i).getFaultCode());
					AlarmLog alarmLog = alarmLogDao.selectEntityByCondition(equipmentAlarmLog);
					if (alarmLog != null) {// 查询是否存在此设备的此故障码记录,存在则只更新次数+1
						alarmLogDao.updateCount(equipmentAlarmLog);
					} else {
						equipmentAlarmLog.setWorkOrderCode(awo.getCode());
						equipmentAlarmLog.setFirstTime(String.valueOf(System.currentTimeMillis()));
						equipmentAlarmLog.setCount(DEFAULT_COUNT);
						returnCode = alarmLogDao.insert(equipmentAlarmLog);// 插入设备告警记录表，用于统计设备告警次数和告警时间
					}
				}
				if (alarmWorkOrders.get(i).getOemPerson() != null
						&& !alarmWorkOrders.get(i).getOemPerson().equals("null")) {
					// 向工单参与者表插入工单记录，默认设备客户负责人为工单参与者
					String[] paddings = alarmWorkOrders.get(i).getOemPerson().split(CommonUtils.SPLIT_COMMA);
					for (String userCode : paddings) {
						AlarmWorkUser alarmWorkUser = new AlarmWorkUser();
						alarmWorkUser.setCode(code);
						alarmWorkUser.setUserCode(userCode);
						alarmWorkUser.setUserCode(userCode);
						alarmWorkUser.setRole(CommonUtils.ALARM_ROLE_PARTIN);
						returnCode = alarmWorkUserDao.insert(alarmWorkUser);
					}
				}
				redis.select(Integer.parseInt(PropertiesUtils.findPropertiesKey("redis.db.fault")));
				if (i == 0) {
					returnCode = alarmWorkOrdersDao.insert(awo);
					WorkOrderLogs workOrderLogs = new WorkOrderLogs();
					workOrderLogs.setWorkOrderCode(code);
					workOrderLogs.setType(1);// 文字
					workOrderLogs.setCustomerCode(awo.getCustomerCode());
					workOrderLogs.setUserCode(alarmWorkOrders.get(i).getOemPerson());
					workOrderLogs.setOperation(CommonUtils.OPERATION_NOTRESOLVER);
					workOrderLogs.setContent(awo.getDescription() + awo.getHandingSuggestion());
					workOrderLogs.setSolution(awo.getHandingSuggestion());
					workOrderLogsDao.insert(workOrderLogs);
					// 更新设备状态为故障
					Equipments equipment = new Equipments();
					equipment.setCode(awo.getEquipmentCode());
					equipment.setCurrentState(CommonUtils.EQU_STATE_FAULT);
					returnCode = equipmentsDao.updateCurrentStateByCondition(equipment);
					/*
					 * // 统计我的工单 用于推送 redis.hset(awo.getPaddingBy(), awo.getCode(), MY_FAULT_TOTAL);
					 */
					// 给工单责任人发送邮件
					Map<String, Object> condition = new HashMap<String, Object>();
					condition.put("language", awo.getLanguage());
					condition.put("code", awo.getCode());
					condition = alarmWorkOrdersDao.selectMapByCondition(condition);
					try {
						if (condition != null && condition.get("usertype").equals(CommonUtils.LOGIN_ADMIN_TYPE)) {
							MailSenderUtil.sendMail(String.valueOf(condition.get("email")),
									String.valueOf(condition.get("comname")) + ":"
											+ String.valueOf(condition.get("name")) + ":" + awo.getFaultCode(),
									awo.getDescription() + "\r\n" + awo.getHandingSuggestion() + "\r\n"
											+ PropertiesUtils.findPropertiesKey("website.address")
											+ "/yun/admin/#/page/workorder/detail/" + awo.getCode(),
									1);
						}
						if (condition != null && condition.get("usertype").equals(CommonUtils.LOGIN_CUSTORER_TYPE)) {
							MailSenderUtil.sendMail(String.valueOf(condition.get("email")),
									String.valueOf(condition.get("comname")) + ":"
											+ String.valueOf(condition.get("name")) + ":" + awo.getFaultCode(),
									awo.getDescription() + "\r\n" + awo.getHandingSuggestion() + "\r\n"
											+ PropertiesUtils.findPropertiesKey("website.address")
											+ "/yun/user/#/page/workorder/detail/" + awo.getCode(),
									1);
						}
					} catch (Exception e) {
						logger.error("AlarmSendEmail Error \r{}", e);
					}
				}
				returnCode = alarmWorkOrdersDao.insertInfo(awo);
				Map<String, Object> map = new HashMap<String, Object>();
				alarmWorkOrders.get(i).setFirstTime(awo.getFirstTime());
				alarmWorkOrders.get(i).setCode(awo.getCode());
				map.put("model", alarmWorkOrders.get(i));
				ObjectMapper mapper = new ObjectMapper();
				mapper.setSerializationInclusion(Include.NON_NULL);
				Equipments equipment = new Equipments();
				equipment.setCode(awo.getEquipmentCode());
				equipment.setLanguage(awo.getLanguage());
				equipment = equipmentsDao.selectEntityByCondition(equipment);
				awo.setEquipment(equipment);
				Companies company = new Companies();
				company.setCode(awo.getCustomerCode());
				company.setLanguage(awo.getLanguage());
				company = companiesDao.selectEntityByCondition(company);
				awo.setCompany(company);
				redis.hset(awo.getCustomerCode() + FAULT_REDIS_SPILT + awo.getLanguage(), awo.getCode(),
						mapper.writeValueAsString(map));
				// 推送工单
				sendAlarmWebSocket(awo, redis);
				sendAlarmWebSocketAfterLogin(awo, redis);
			}
		} catch (Exception e) {
			logger.error("工单Logic异常 \r{}", e);
			returnCode = 0;
		} finally {
			redisPool.returnResource(redis);
		}
		return returnCode;
	}
	public int update(AlarmWorkOrders alarmWorkOrders) {
		int returnCode = 0;
		alarmWorkOrders.setLastUpdateTime(String.valueOf(System.currentTimeMillis()));
		if (alarmWorkOrders.getOrderStatus() != null
				&& alarmWorkOrders.getOrderStatus().equals(CommonUtils.ORDER_STATUS_CLOSE)) {
			Jedis redis = null;
			try {
				redis = redisPool.getResource();
				redis.select(Integer.parseInt(PropertiesUtils.findPropertiesKey("redis.db.fault")));
				String total = redis.hget(alarmWorkOrders.getFaultChannelCode(), alarmWorkOrders.getFaultCode());
				if (total != null) {
					redis.hdel(alarmWorkOrders.getFaultChannelCode(), alarmWorkOrders.getFaultCode());
				} else {
					total = redis.hget(alarmWorkOrders.getFaultChannelCode(), alarmWorkOrders.getFaultCode() + ".0");
					if (total != null) {
						long result = redis.hdel(alarmWorkOrders.getFaultChannelCode(),
								alarmWorkOrders.getFaultCode() + ".0");
						logger.error("result------------\t", result);
					} else {
						total = redis.hget(alarmWorkOrders.getFaultChannelCode(),
								alarmWorkOrders.getFaultCode() + ".00");
						long result = redis.hdel(alarmWorkOrders.getFaultChannelCode(),
								alarmWorkOrders.getFaultCode() + ".00");
						logger.error("result------------\t", result);
					}
				}
				// 更新设备状态为故障
				Equipments equipment = new Equipments();
				equipment.setCode(alarmWorkOrders.getEquipmentCode());
				equipment.setCurrentState(CommonUtils.EQU_STATE_NORMAL);
				equipmentsDao.updateCurrentStateByCondition(equipment);
				// 修改故障单统计表的处理时间和处理时长
				FaultStat faultStat = new FaultStat();
				faultStat.setAlarmWorkCode(alarmWorkOrders.getCode());
				faultStat = faultsDao.selectFaultStatByCondition(faultStat);
				if (faultStat != null) {
					faultStat.setRecoveryTime(alarmWorkOrders.getLastUpdateTime());
					faultStat.setDuration(BigDecimal.valueOf(
							(Long.parseLong(faultStat.getRecoveryTime()) - Long.parseLong(faultStat.getFailureTime()))
									/ 3600000));
					faultsDao.updateFaultStatByCondition(faultStat);
				}
			} catch (Exception e) {
				logger.error("工单处理异常\t {}", e);
			} finally {
				redisPool.returnResource(redis);
			}
		}
		returnCode = alarmWorkOrdersDao.updateByCondition(alarmWorkOrders);
		return returnCode;
	}
	@Override
	public List<AlarmWorkOrders> selectListWhere(AlarmWorkOrders alarmWorkOrders) {
		return alarmWorkOrdersDao.selectOrderStatusByCondition(alarmWorkOrders);
	}
	/**
	 * selectListHistory 历史故障
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @param @param equipmentCode
	 * @param @return 参数
	 * @return List<AlarmWorkOrders> 返回类型
	 */
	@Override
	public List<AlarmWorkOrders> selectListHistory(AlarmWorkOrders alarmWorkOrdersWhere) {
		List<AlarmWorkOrders> alarmWorkOrdersHistory = selectListWhere(alarmWorkOrdersWhere);
		if (alarmWorkOrdersHistory != null && alarmWorkOrdersHistory.size() >= FAULT_LIKE_HIS_SIZE_END) {
			alarmWorkOrdersHistory = alarmWorkOrdersHistory.subList(FAULT_LIKE_HIS_SIZE_START, FAULT_LIKE_HIS_SIZE_END);
		}
		// 查询解决方案
		for (AlarmWorkOrders alarm : alarmWorkOrdersHistory) {
			WorkOrderLogs log = new WorkOrderLogs();
			log.setWorkOrderCode(alarm.getCode());
			log.setLanguage(alarmWorkOrdersWhere.getLanguage());
			log.setOperation(CommonUtils.OPERATION_HANDLE);
			log = workOrderLogsDao.selectEntityByCondition(log);
			if (log != null) {
				alarm.setSolution(log.getSolution());
			}
		}
		return alarmWorkOrdersHistory;
	}
	/**
	 * selectListLike
	 * @Description: 类似故障
	 * @param @param faultCode
	 * @param @return 参数
	 * @return List<AlarmWorkOrders> 返回类型
	 */
	@Override
	public List<AlarmWorkOrders> selectListLike(AlarmWorkOrders alarmWorkOrdersWhere) {
		List<AlarmWorkOrders> alarmWorkOrdersLike = selectListWhere(alarmWorkOrdersWhere);
		if (alarmWorkOrdersLike != null && alarmWorkOrdersLike.size() >= FAULT_LIKE_HIS_SIZE_END) {
			alarmWorkOrdersLike = alarmWorkOrdersLike.subList(FAULT_LIKE_HIS_SIZE_START, FAULT_LIKE_HIS_SIZE_END);
		}
		// 查询解决方案
		for (AlarmWorkOrders alarm : alarmWorkOrdersLike) {
			WorkOrderLogs log = new WorkOrderLogs();
			log.setWorkOrderCode(alarm.getCode());
			log.setLanguage(alarmWorkOrdersWhere.getLanguage());
			log.setOperation(CommonUtils.OPERATION_HANDLE);
			log = workOrderLogsDao.selectEntityByCondition(log);
			if (log != null) {
				alarm.setSolution(log.getSolution());
			}
		}
		return alarmWorkOrdersLike;
	}
	@Override
	public int updateCount(AlarmWorkOrders alarmWorkOrders) {
		return alarmWorkOrdersDao.updateCountByCondition(alarmWorkOrders);
	}
	@Override
	public Map<String, Object> selecAllOrderStatus(AlarmWorkOrders alarmWorkOrdersWhere) {
		// 未处理
		alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_NEW);
		List<AlarmWorkOrders> alarmWorkOrdersUntreated = selectListWhere(alarmWorkOrdersWhere);
		// 处理中
		alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_HANDLE);
		List<AlarmWorkOrders> alarmWorkOrdersHandle = selectListWhere(alarmWorkOrdersWhere);
		// 已处理
		alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_CLOSE);
		List<AlarmWorkOrders> alarmWorkOrdersClose = selectListWhere(alarmWorkOrdersWhere);
		// 已查阅
		/*
		 * alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_READED);
		 * List<AlarmWorkOrders> alarmWorkOrdersSee = selectListWhere(alarmWorkOrdersWhere);
		 */
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("alarmUntreateds", alarmWorkOrdersUntreated.size());
		map.put("alarmHandles", alarmWorkOrdersHandle.size());
		map.put("alarmCloses", alarmWorkOrdersClose.size());
		map.put("alarmCount",
				alarmWorkOrdersUntreated.size() + alarmWorkOrdersHandle.size() + alarmWorkOrdersClose.size());
		return map;
	}
	@Override
	public List<WorkOrderLogs> selectWorkOrderLogsList(PageModel page, WorkOrderLogs work) {
		if (page.getIndex() != null && page.getSize() != null) {
			PageHelper.startPage(page.getIndex(), page.getSize(), false, false);
		}
		List<WorkOrderLogs> workOrderLogs = workOrderLogsDao.selectListByCondition(work);
		for (WorkOrderLogs log : workOrderLogs) {
			Attach attach = new Attach();
			attach.setObjectId(log.getId());
			attach.setType(AttachLogicImpl.ATTACH_WORKORDER_TYPE);
			log.setImages(attachDao.selectListByCondition(attach));
		}
		return workOrderLogs;
	}
	@Override
	public int saveWorkOrderLogs(WorkOrderLogs workOrderLogs) {
		int returnCode = workOrderLogsDao.insert(workOrderLogs);
		return returnCode;
	}
	@Override
	public int selectWorkOrdersTotalByCustomerCode(String comCode) {
		return alarmWorkOrdersDao.selectWorkOrdersTotalByCustomerCode(comCode);
	}
	@Override
	public Map<String, Object> search(PageModel page, Map<String, Object> params) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<AlarmWorkOrders> result = Collections.emptyList();
		if (page.getIndex() != null && page.getSize() > 0) {
			PageHelper.startPage(page.getIndex(), page.getSize());
			Page<AlarmWorkOrders> pages = (Page<AlarmWorkOrders>) alarmWorkOrdersDao.search(params);
			result = alarmWorkOrdersDao.search(params);
			map = new HashMap<String, Object>();
			map.put("list", pages);
			map.put("total", pages.getTotal());
		} else {
			result = alarmWorkOrdersDao.search(params);
			map = new HashMap<String, Object>();
			map.put("list", result);
		}
		map.put("alarmUntreateds", CommonUtils.DEFAULT_NUM);
		map.put("alarmHandles", CommonUtils.DEFAULT_NUM);
		map.put("alarmCloses", CommonUtils.DEFAULT_NUM);
		map.put("alarmSees", CommonUtils.DEFAULT_NUM);
		for (AlarmWorkOrders alarm : result) {
			if (alarm.getOrderStatus() == CommonUtils.ORDER_STATUS_CLOSE) {
				map.put("alarmCloses", (Integer) map.get("alarmCloses") + 1);
			} else if (alarm.getOrderStatus() == CommonUtils.ORDER_STATUS_HANDLE) {
				map.put("alarmHandles", (Integer) map.get("alarmHandles") + 1);
			} else if (alarm.getOrderStatus() == CommonUtils.ORDER_STATUS_NEW) {
				map.put("alarmUntreateds", (Integer) map.get("alarmUntreateds") + 1);
			}
		}
		return map;
	}
	@Override
	public int selectUndoneWorkOrdersTotalByOemCode(Companies company) {
		return alarmWorkOrdersDao.selectUndoneWorkOrdersTotalByOemCode(company);
	}
	@Override
	public List<AlarmWorkOrders> selectFaultInfoByChannelAndFaultCode(String channel, String faultCode) {
		return alarmWorkOrdersDao.selectFaultInfoByChannelAndFaultCode(channel, faultCode);
	}
	@Override
	public Map<String, Object> selectMap(Map<String, Object> condition) {
		Map<String, Object> alarm = alarmWorkOrdersDao.selectMapByCondition(condition);
		if (alarm != null && alarm.get("equcode") != null) {
			WorkOrderLogs log = new WorkOrderLogs();
			log.setUserCode((String) alarm.get("equcode"));
			log.setLanguage((String) condition.get("language"));
			log = workOrderLogsDao.selectEntityByCondition(log);
			if (log != null && log.getSubmitTime() != null) {
				alarm.put("lastFaultTime", log.getSubmitTime());
			} else {
				log = new WorkOrderLogs();
				log.setWorkOrderCode((String) condition.get("code"));
				log.setLanguage((String) condition.get("language"));
				log = workOrderLogsDao.selectEntityByCondition(log);
				if (log != null && log.getSubmitTime() != null) {
					alarm.put("lastFaultTime", log.getSubmitTime());
				} else {
					alarm.put("lastFaultTime", alarm.get("firstTime"));
				}
			}
		}
		if (alarm != null) {
			if (alarm.get("oems") != null) {
				List<AuthUsers> users = new ArrayList<AuthUsers>();
				String[] userCode = String.valueOf(alarm.get("oems")).split(",");
				for (int i = 0; i < userCode.length; i++) {
					AuthUsers user = new AuthUsers();
					user.setCode(userCode[i]);
					user.setLanguage((String) condition.get("language"));
					AuthUsers oem = authUserDao.selectEntityByCondition(user);
					if (oem != null) {
						users.add(oem);
					}
				}
				alarm.put("oems", users);
			}
			if (alarm.get("suppliers") != null) {
				List<AuthUsers> users = new ArrayList<AuthUsers>();
				String[] userCode = String.valueOf(alarm.get("suppliers")).split(",");
				for (int i = 0; i < userCode.length; i++) {
					AuthUsers user = new AuthUsers();
					user.setCode(userCode[i]);
					user.setLanguage((String) condition.get("language"));
					AuthUsers supplier = authUserDao.selectEntityByCondition(user);
					if (supplier != null) {
						users.add(supplier);
					}
				}
				alarm.put("suppliers", users);
			}
			if (alarm.get("customers") != null) {
				List<AuthUsers> users = new ArrayList<AuthUsers>();
				String[] userCode = String.valueOf(alarm.get("customers")).split(",");
				for (int i = 0; i < userCode.length; i++) {
					AuthUsers user = new AuthUsers();
					user.setCode(userCode[i]);
					user.setLanguage((String) condition.get("language"));
					AuthUsers customer = authUserDao.selectEntityByCondition(user);
					if (customer != null) {
						users.add(customer);
					}
				}
				alarm.put("customers", users);
			}
		}
		if (alarm != null && alarm.get("firstTime") != null) {
			alarm.put("pastTime", CommonUtils.getDistanceTime(System.currentTimeMillis(),
					Long.parseLong(String.valueOf(alarm.get("firstTime"))), 2));
		}
		return alarm;
	}
	@Override
	public Map<String, Object> selecAlarmsByUserCode(AlarmWorkOrders alarmWorkOrdersWhere) {
		// 未处理
		alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_NEW);
		List<AlarmWorkOrders> alarmWorkOrdersUntreated = selectListWhere(alarmWorkOrdersWhere);
		// 处理中
		alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_HANDLE);
		List<AlarmWorkOrders> alarmWorkOrdersHandle = selectListWhere(alarmWorkOrdersWhere);
		// 已处理
		alarmWorkOrdersWhere.setOrderStatus(CommonUtils.ORDER_STATUS_CLOSE);
		List<AlarmWorkOrders> alarmWorkOrdersClose = selectListWhere(alarmWorkOrdersWhere);
		/**
		 * 计算平均处理时长 总处理完成工单时间/工单总数/3600=平均1个工单的处理时间 单位 1个/小时
		 */
		int size = alarmWorkOrdersClose.size();
		float avgtime = 0;
		if (size > 0) {
			float countTime = 0;
			for (int i = 0; i < size; i++) {
				countTime += Long.parseLong(alarmWorkOrdersClose.get(i).getLastUpdateTime())
						- Long.parseLong(alarmWorkOrdersClose.get(i).getFirstTime());
			}
			avgtime = countTime / ONE_DATE_SECONDS / size;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("total", alarmWorkOrdersUntreated.size() + alarmWorkOrdersHandle.size() + alarmWorkOrdersClose.size());
		map.put("close", alarmWorkOrdersClose.size());
		map.put("newest", alarmWorkOrdersUntreated.size());
		map.put("handle", alarmWorkOrdersHandle.size());
		map.put("avgtime", CommonUtils.strFormatTwoDecimal(String.valueOf(avgtime)));
		HelpWorkOrder helpWorkOrder = new HelpWorkOrder();
		helpWorkOrder.setCustomerCode(alarmWorkOrdersWhere.getCustomerCode());
		helpWorkOrder.setPaddingBy(alarmWorkOrdersWhere.getPaddingBy());
		helpWorkOrder.setLanguage(alarmWorkOrdersWhere.getLanguage());
		List<HelpWorkOrder> helpAlarmList = helpWorkOrderDao.selectListByCondition(helpWorkOrder);
		for (HelpWorkOrder help : helpAlarmList) {
			if (help.getOrderStatus() == CommonUtils.ORDER_STATUS_NEW) {
				map.put("newest", (int) map.get("newest") + 1);
				map.put("total", (int) map.get("total") + 1);
			} else if (help.getOrderStatus() == CommonUtils.ORDER_STATUS_CLOSE) {
				map.put("close", (int) map.get("close") + 1);
				map.put("total", (int) map.get("total") + 1);
			} else if (help.getOrderStatus() == CommonUtils.ORDER_STATUS_HANDLE) {
				map.put("handle", (int) map.get("handle") + 1);
				map.put("total", (int) map.get("total") + 1);
			}
		}
		return map;
	}
	@Override
	public List<AlarmWorkOrders> selectAlarmWorksByUser(AlarmWorkOrders alarmWorkOrders) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("oemCode", alarmWorkOrders.getOemCode());
		map.put("comCode", alarmWorkOrders.getCustomerCode());
		map.put("agentCode", alarmWorkOrders.getAgentCode());
		map.put("orderStatus", alarmWorkOrders.getOrderStatus());
		map.put("language", alarmWorkOrders.getLanguage());
		List<AlarmWorkOrders> result = Collections.emptyList();
		map.put("paddingBy", alarmWorkOrders.getPaddingBy());
		result = alarmWorkOrdersDao.search(map);
		return result;
	}
	@Override
	public Page<AlarmWorkOrders> selectAlarmWorksByUser(AlarmWorkOrders alarmWorkOrder, int index, int size) {
		PageHelper.startPage(index, size);
		return (Page<AlarmWorkOrders>) alarmWorkOrdersDao.selectAlarmWorksByUser(alarmWorkOrder);
	}
	/**
	 * 推送工单，根据客户去判断推送 SendAlarmWebsocket
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @param @param awo
	 * @param @param redis
	 * @param @throws IOException 参数
	 * @return void 返回类型
	 */
	public void sendAlarmWebSocket(AlarmWorkOrders awo, Jedis redis) throws IOException {
		// 遍历所有连接客户工单WebSocket 推送客户下的所有工单 区分多语言
		Iterator<Map.Entry<String, CustomerAlarmWebsocket>> customerAlarmEntries = CustomerAlarmWebsocket.webSocketMap
				.entrySet().iterator();
		while (customerAlarmEntries.hasNext()) {
			Map.Entry<String, CustomerAlarmWebsocket> customerEntry = customerAlarmEntries.next();
			if (customerEntry.getKey().contains(awo.getCustomerCode() + FAULT_REDIS_SPILT + awo.getLanguage())) {
				if (customerEntry.getKey().split(FAULT_REDIS_SPILT)[1].equals(awo.getLanguage())) {
					Map<String, String> map = redis
							.hgetAll(awo.getCustomerCode() + FAULT_REDIS_SPILT + awo.getLanguage());
					Iterator<Map.Entry<String, String>> values = map.entrySet().iterator();
					while (values.hasNext()) {
						Map.Entry<String, String> value = values.next();
						if (!redis.sismember(customerEntry.getKey(), value.getKey())) {
							customerEntry.getValue().sendMessage(value.getValue());
							redis.sadd(customerEntry.getKey(), value.getKey());
						}
					}
				}
			}
		}
		// 遍历所有连接我的工单WebSocket 只推送当前工单数量
		Iterator<Map.Entry<String, MyAlarmWebsocket>> myAlarmEntries = MyAlarmWebsocket.webSocketMap.entrySet()
				.iterator();
		while (myAlarmEntries.hasNext()) {
			Map.Entry<String, MyAlarmWebsocket> myEntry = myAlarmEntries.next();
			if (myEntry.getKey().contains(awo.getPaddingBy())) {
				Map<String, String> map = redis.hgetAll(awo.getPaddingBy());
				myEntry.getValue().sendMessage(String.valueOf(map.size()));
			}
		}
	}
	public void sendAlarmWebSocketAfterLogin(AlarmWorkOrders awo, Jedis redis) throws IOException {
		// 遍历所有连接工单增量WebSocket 推送工单增量给客户，oem，admin 区分多语言
		Iterator<Map.Entry<String, AlarmDialogueWebsocket>> alarmWorkOrderEntries = AlarmDialogueWebsocket.webSocketMap
				.entrySet().iterator();
		while (alarmWorkOrderEntries.hasNext()) {
			Map.Entry<String, AlarmDialogueWebsocket> alarmWorkOrderEntry = alarmWorkOrderEntries.next();
			String type = alarmWorkOrderEntry.getKey().split(FAULT_REDIS_SPILT)[2];
			if (type.equals(CommonUtils.CUSTORER_TYPE)) {
				if (alarmWorkOrderEntry.getKey()
						.contains(awo.getCustomerCode() + FAULT_REDIS_SPILT + awo.getLanguage())) {
					ObjectMapper mapper = new ObjectMapper();
					mapper.setSerializationInclusion(Include.NON_NULL);
					if (!redis.sismember(alarmWorkOrderEntry.getKey(), awo.getCode())) {
						alarmWorkOrderEntry.getValue().sendMessage(mapper.writeValueAsString(awo));
						redis.sadd(alarmWorkOrderEntry.getKey(), awo.getCode());
					}
				}
			} else if (type.equals(CommonUtils.OEM_TYPE)) {
				String customerCode = awo.getCustomerCode();
				Companies company = new Companies();
				company.setCode(customerCode);
				String oemCode = companiesDao.selectEntityByCondition(company).getOemCode();
				if (alarmWorkOrderEntry.getKey().contains(oemCode + FAULT_REDIS_SPILT + awo.getLanguage())) {
					ObjectMapper mapper = new ObjectMapper();
					mapper.setSerializationInclusion(Include.NON_NULL);
					if (!redis.sismember(alarmWorkOrderEntry.getKey(), awo.getCode())) {
						alarmWorkOrderEntry.getValue().sendMessage(mapper.writeValueAsString(awo));
						redis.sadd(alarmWorkOrderEntry.getKey(), awo.getCode());
					}
				}
			} else if (type.equals(CommonUtils.ADMIN_TYPE)) {
				ObjectMapper mapper = new ObjectMapper();
				mapper.setSerializationInclusion(Include.NON_NULL);
				if (!redis.sismember(alarmWorkOrderEntry.getKey(), awo.getCode())) {
					alarmWorkOrderEntry.getValue().sendMessage(mapper.writeValueAsString(awo));
					redis.sadd(alarmWorkOrderEntry.getKey(), awo.getCode());
				}
			}
		}
	}
	public void sendHomeMapAlarm(AlarmWorkOrders awo, Jedis redis) throws IOException {
		// 遍历所有连接工单增量WebSocket 推送工单增量给客户，oem，admin 区分多语言
		Iterator<Map.Entry<String, HomeMapAlarmWebsocket>> alarmWorkOrderEntries = HomeMapAlarmWebsocket.webSocketMap
				.entrySet().iterator();
		while (alarmWorkOrderEntries.hasNext()) {
			Map.Entry<String, HomeMapAlarmWebsocket> alarmWorkOrderEntry = alarmWorkOrderEntries.next();
			String type = alarmWorkOrderEntry.getKey().split(FAULT_REDIS_SPILT)[2];
			if (type.equals(CommonUtils.CUSTORER_TYPE)) {
				if (alarmWorkOrderEntry.getKey()
						.contains(awo.getCustomerCode() + FAULT_REDIS_SPILT + awo.getLanguage())) {
					Companies company = new Companies();
					// 设备客户故障为1
					company.setIsError(CommonUtils.SUCCESS_NUM);
					// 查询故障设备信息
					Equipments equipment = new Equipments();
					equipment.setCode(awo.getEquipmentCode());
					equipment.setLanguage(awo.getLanguage());
					Equipments errorEquipment = equipmentsDao.selectEntityByCondition(equipment);
					List<Equipments> errorEqus = new ArrayList<Equipments>();
					errorEqus.add(errorEquipment);
					company.setErrorEquipments(errorEqus);
					ObjectMapper mapper = new ObjectMapper();
					mapper.setSerializationInclusion(Include.NON_NULL);
					if (!redis.sismember(alarmWorkOrderEntry.getKey(), awo.getCode())) {
						alarmWorkOrderEntry.getValue().sendMessage(mapper.writeValueAsString(company));
						redis.sadd(alarmWorkOrderEntry.getKey(), awo.getCode());
					}
				}
			} else if (type.equals(CommonUtils.OEM_TYPE)) {
				String customerCode = awo.getCustomerCode();
				Companies company = new Companies();
				company.setCode(customerCode);
				String oemCode = companiesDao.selectEntityByCondition(company).getOemCode();
				if (alarmWorkOrderEntry.getKey().contains(oemCode + FAULT_REDIS_SPILT + awo.getLanguage())) {
					company = new Companies();
					// 设备客户故障为1
					company.setIsError(CommonUtils.SUCCESS_NUM);
					// 查询故障设备信息
					Equipments equipment = new Equipments();
					equipment.setCode(awo.getEquipmentCode());
					equipment.setLanguage(awo.getLanguage());
					Equipments errorEquipment = equipmentsDao.selectEntityByCondition(equipment);
					List<Equipments> errorEqus = new ArrayList<Equipments>();
					errorEqus.add(errorEquipment);
					company.setErrorEquipments(errorEqus);
					ObjectMapper mapper = new ObjectMapper();
					mapper.setSerializationInclusion(Include.NON_NULL);
					if (!redis.sismember(alarmWorkOrderEntry.getKey(), awo.getCode())) {
						alarmWorkOrderEntry.getValue().sendMessage(mapper.writeValueAsString(company));
						redis.sadd(alarmWorkOrderEntry.getKey(), awo.getCode());
					}
				}
			} else if (type.equals(CommonUtils.ADMIN_TYPE)) {
				ObjectMapper mapper = new ObjectMapper();
				mapper.setSerializationInclusion(Include.NON_NULL);
				if (!redis.sismember(alarmWorkOrderEntry.getKey(), awo.getCode())) {
					Companies company = new Companies();
					// 设备客户故障为1
					company.setIsError(CommonUtils.SUCCESS_NUM);
					// 查询故障设备信息
					Equipments equipment = new Equipments();
					equipment.setCode(awo.getEquipmentCode());
					equipment.setLanguage(awo.getLanguage());
					Equipments errorEquipment = equipmentsDao.selectEntityByCondition(equipment);
					List<Equipments> errorEqus = new ArrayList<Equipments>();
					errorEqus.add(errorEquipment);
					company.setErrorEquipments(errorEqus);
					alarmWorkOrderEntry.getValue().sendMessage(mapper.writeValueAsString(company));
					redis.sadd(alarmWorkOrderEntry.getKey(), awo.getCode());
				}
			}
		}
	}
	@Override
	public List<AlarmWorkOrders> selectEquipmentFaultProportion(AlarmWorkOrders alarmWorkOrder, long startTime,
			long endTime) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("language", alarmWorkOrder.getLanguage());
		map.put("oemCode", alarmWorkOrder.getOemCode());
		// map.put("startTime", startTime);
		// map.put("endTime", endTime);
		map.put("equipmentCode", alarmWorkOrder.getEquipmentCode());
		map.put("orderStatus", alarmWorkOrder.getOrderStatus());
		map.put("customerCode", alarmWorkOrder.getCustomerCode());
		return alarmWorkOrdersDao.selectEquipmentFaultProportion(map);
	}
	@Override
	public Map<String, Object> searchAlarmAndHelp(PageModel page, String country, String province, String city,
			String key, AlarmWorkOrders alarm) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("oemCode", alarm.getOemCode());
		map.put("comCode", alarm.getCustomerCode());
		map.put("agentCode", alarm.getAgentCode());
		map.put("country", country);
		map.put("province", province);
		map.put("city", city);
		map.put("keyword", key);
		map.put("orderStatus", alarm.getOrderStatus());
		map.put("language", alarm.getLanguage());
		List<AlarmWorkOrders> result = Collections.emptyList();
		map.put("paddingBy", alarm.getPaddingBy());
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("oemCode", alarm.getOemCode());
		paramMap.put("comCode", alarm.getCustomerCode());
		paramMap.put("agentCode", alarm.getAgentCode());
		paramMap.put("language", alarm.getLanguage());
		// 未处理
		paramMap.put("orderStatus", CommonUtils.ORDER_STATUS_NEW);
		List<AlarmWorkOrders> alarmWorkOrdersUntreated = alarmWorkOrdersDao.searchAlarmAndHelp(paramMap);
		// 处理中
		paramMap.put("orderStatus", CommonUtils.ORDER_STATUS_HANDLE);
		List<AlarmWorkOrders> alarmWorkOrdersHandle = alarmWorkOrdersDao.searchAlarmAndHelp(paramMap);
		// 已处理
		paramMap.put("orderStatus", CommonUtils.ORDER_STATUS_CLOSE);
		List<AlarmWorkOrders> alarmWorkOrdersClose = alarmWorkOrdersDao.searchAlarmAndHelp(paramMap);
		result = alarmWorkOrdersDao.searchAlarmAndHelp(map);
		if (page.getIndex() != null && page.getSize() != null) {
			PageHelper.startPage(page.getIndex(), page.getSize());
			Page<AlarmWorkOrders> pages = (Page<AlarmWorkOrders>) alarmWorkOrdersDao.searchAlarmAndHelp(map);
			map = new HashMap<String, Object>();
			map.put("list", pages);
			map.put("total", pages.getTotal());
		} else {
			map = new HashMap<String, Object>();
			map.put("list", result);
		}
		map.put("alarmUntreateds", alarmWorkOrdersUntreated.size());
		map.put("alarmHandles", alarmWorkOrdersHandle.size());
		map.put("alarmCloses", alarmWorkOrdersClose.size());
		return map;
	}
	@Override
	public int receiveAlarmWorkOrder(AlarmWorkUser alarmWorkUser) {
		AlarmWorkUser model = alarmWorkUserDao.selectEntityByCondition(alarmWorkUser);
		if (model != null) {
			model.setRole(alarmWorkUser.getRole());
			int returnCode = alarmWorkUserDao.updateByCondition(model);
			return returnCode;
		}
		int returnCode = alarmWorkUserDao.insert(alarmWorkUser);
		return returnCode;
	}
	@Override
	public int sendMesssageToDialogueWebSocket(String content) {
		// 遍历所有连接客户工单WebSocket 推送对话
		Iterator<Map.Entry<String, AlarmDialogueWebsocket>> customerAlarmEntries = AlarmDialogueWebsocket.webSocketMap
				.entrySet().iterator();
		while (customerAlarmEntries.hasNext()) {
			Map.Entry<String, AlarmDialogueWebsocket> alarmDialogueWebsocketEntry = customerAlarmEntries.next();
			try {
				alarmDialogueWebsocketEntry.getValue().sendMessage(content);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return 0;
	}
	@Override
	public Map<String, Object> selectAgencyWorkOrderList(PageModel page, Map<String, Object> params) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<AlarmWorkOrders> result = Collections.emptyList();
		if (page.getIndex() != null && page.getSize() > 0) {
			PageHelper.startPage(page.getIndex(), page.getSize());
			Page<AlarmWorkOrders> pages = (Page<AlarmWorkOrders>) alarmWorkOrdersDao.selectAgencyWorkOrderList(params);
			map = new HashMap<String, Object>();
			map.put("list", pages);
			map.put("total", pages.getTotal());
		} else {
			result = alarmWorkOrdersDao.search(params);
			map = new HashMap<String, Object>();
			map.put("list", result);
		}
		return map;
	}
	@Override
	public List<AlarmWorkOrders> selectUntreatedWorkOrder(String categoryCode, Integer orderStatus) {
		return alarmWorkOrdersDao.selectUntreatedWorkOrder(categoryCode, orderStatus);
	}
}
